﻿using Microsoft.Extensions.Logging;
using Serilog;
using ShanNiang.AutoUpdate.Service.Interfaces;
using ShanNiang.AutoUpdate.Service.Responses;
using ShanNiang.Hosting;
using ShanNiang.Hosting.Common;
using ShanNiang.Hosting.Enumerate;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Http.Json;
using System.Reflection;
using System.Runtime.Versioning;

namespace ShanNiang.AutoUpdate.Service.Implementations
{
    /// <summary>
    /// 检测版本
    /// </summary>
    [SupportedOSPlatform("windows")]
    public class CheckVersionService : LocalService, ICheckVersionService
    {
        private readonly AutoUpdateConfig _autoUpdateConfig;
        /// <summary>
        /// 版本号文件路径
        /// </summary>
        public const string UserApplicationPath = "SnSoft/AutoUpdate";

        public readonly string VersionFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), UserApplicationPath);

        //private Timer? _timer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="autoUpdateConfigOption"></param>
        public CheckVersionService(AutoUpdateConfig autoUpdateConfig, ILogger<CheckVersionService> logger) : base(logger)
        {
            _autoUpdateConfig = autoUpdateConfig;
        }
        /// <summary>
        /// 先查询本地的version 文本文件
        /// 如果没有则查询  主程序集的 版本号
        /// 都没有则返回  0.0
        /// </summary>
        /// <returns></returns>
        public Version GetLocalVersion(Assembly? assembly)
        {
            if (assembly != null)
            {
                var version = assembly.GetName().Version;
                if (version != null)
                {
                    return version;
                }
            }
            return new Version();
        }
        /// <summary>
        /// 获取远程版本
        /// </summary>
        /// <returns></returns>
        /// <exception cref="HttpRequestException"></exception>
        public async Task<PublishedClientResponse?> GetRemoteVersionAsync()
        {
            try
            {
                var client = new HttpClient();
                var resp = await client.GetAsync($"{_autoUpdateConfig.GetRemoveVersionUrl}");
                if (!resp.IsSuccessStatusCode)
                {
                    throw new HttpRequestException("查找更新失败", null, resp.StatusCode);
                }
                var result = resp.Content.ReadFromJsonAsync<ApiResult<PublishedClientResponse>>().Result;
                if (result != null && result.Code == GlobalErrorCode.Ok && result.Data != null)
                {
                    return result.Data;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "获取远程版本报错");
            }
            return null;
        }
        public async Task<bool> NeedToUpdateAsync(Assembly? assembly)
        {
            Logger.LogInformation($"检测版本。。");
            //var assembly = typeof(CheckVersionService).Assembly;
            //var mainProcessFileName = Path.Combine(Environment.CurrentDirectory, $"{_autoUpdateConfig.MainProcessName}.exe");
            //if (Path.Exists(mainProcessFileName))
            //{
            //    assembly = Assembly.LoadFrom(mainProcessFileName);
            //}
            var localVersion = GetLocalVersion(assembly);
            var response = await GetRemoteVersionAsync();
            if (response != null && localVersion.CompareTo(response.RemoteVersion) < 0)
            {
                return true;
            }
            else
            {
                Log.Logger.Debug($"版本足够新，不用更新。Local:{localVersion};Remote{response?.RemoteVersion};");
                return false;
            }
        }
        public void SetLocalVersion(string version)
        {
            if (!Directory.Exists(VersionFilePath))
            {
                Directory.CreateDirectory(VersionFilePath);
            }
            var path = Path.Combine(VersionFilePath, _autoUpdateConfig.VersionFile);
            using (var writer = new StreamWriter(path, false))
            {
                writer.WriteLine(version);
            }
        }


        private async Task CheckToUpdate(Assembly? assembly)
        {
            var response = await NeedToUpdateAsync(assembly);
            if (response)
            {
                Process.GetProcessesByName("ShanNiang.AutoUpdate").ToList().ForEach(p => p.Kill());
                Process.Start($"ShanNiang.AutoUpdate.exe");
            }
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            Logger.LogInformation("升级服务开启");
            await CheckToUpdate(Assembly.GetEntryAssembly());
            //_timer = new Timer(CheckToUpdate, null, TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(30));
            //return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            //if (_timer != null)
            //{
            //    _timer.Dispose();
            //    _timer = null;
            //}

            Logger.LogInformation("升级服务停止");
            return Task.CompletedTask;
        }

        //protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        //{
        //    _logger.LogInformation("开始执行");
        //    await CheckVersionAsync(stoppingToken);
        //}
    }
}
